package com.company.genealogy.common.config;

import com.company.genealogy.common.filter.JwtAuthenticationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Arrays;
import java.util.Collections;

/**
 * Spring Security安全配置类
 * 
 * 配置系统的安全策略，包括认证、授权、CORS等。
 * 支持基于角色的访问控制（RBAC），集成JWT认证。
 * 
 * 主要功能：
 * - JWT认证过滤器配置
 * - 基于角色的权限控制
 * - CORS跨域配置
 * - 密码加密配置
 * - 无状态会话管理
 * 
 * 权限级别：
 * - ADMIN：系统管理员，拥有所有权限
 * - CLAN_LEADER：族长，拥有家族管理权限
 * - BRANCH_ADMIN：分支管理员，拥有分支管理权限
 * - MINIAPP：小程序用户，拥有基本查看权限
 * - USER：普通用户，拥有有限权限
 * 
 * @author chenzhixiang
 * @version 1.0
 * @since 2024-01-01
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * JWT认证过滤器
     */
    @Autowired
    private JwtAuthenticationFilter jwtAuthenticationFilter;

    /**
     * 配置HTTP安全策略
     * 
     * 设置认证、授权、CORS等安全配置。
     * 配置不同角色的访问权限。
     * 
     * @param http HTTP安全配置对象
     * @throws Exception 配置异常
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .cors().and()
            .csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            /**
             * 1. 公开接口 - 无需认证
             */
            // 认证相关
            .antMatchers("/api/v1/auth/login", "/api/v1/auth/register", "/api/v1/auth/refresh").permitAll()
            // 静态资源
            .antMatchers("/uploads/**", "/member-photos/**", "/spouse-photos/**", "/favicon.ico").permitAll()
            // 公开API
            .antMatchers("/api/v1/members/export", "/api/v1/familynews/public/**").permitAll()
            // 错误页面
            .antMatchers("/error").permitAll()
            
            /**
             * 2. 系统管理接口 - 仅管理员
             */
            // 用户管理
            .antMatchers(HttpMethod.GET, "/api/v1/users/me").authenticated() // 允许已认证用户获取自己的信息
            .antMatchers(HttpMethod.POST, "/api/v1/users/**").hasRole("ADMIN")
            .antMatchers(HttpMethod.PUT, "/api/v1/users/**").hasRole("ADMIN")
            .antMatchers(HttpMethod.DELETE, "/api/v1/users/**").hasRole("ADMIN")
            // 角色管理
            .antMatchers("/api/v1/roles/**").hasRole("ADMIN")
            // 菜单管理
            .antMatchers("/api/v1/menus/**").hasRole("ADMIN")
            // 系统配置
            .antMatchers("/api/v1/system/**").hasRole("ADMIN")
            
            /**
             * 3. 家族管理接口 - 族长和管理员
             */
            // 家族信息管理
            .antMatchers(HttpMethod.POST, "/api/v1/clan/**").hasAnyRole("ADMIN", "CLAN_LEADER")
            .antMatchers(HttpMethod.PUT, "/api/v1/clan/**").hasAnyRole("ADMIN", "CLAN_LEADER")
            .antMatchers(HttpMethod.DELETE, "/api/v1/clan/**").hasAnyRole("ADMIN", "CLAN_LEADER")
            // 统计数据
            .antMatchers("/api/v1/statistics/**").hasAnyRole("ADMIN", "CLAN_LEADER")
            
            /**
             * 4. 分支管理接口 - 分支管理员及以上
             */
            // 分支信息管理
            .antMatchers(HttpMethod.POST, "/api/v1/branch/**").hasAnyRole("ADMIN", "CLAN_LEADER", "BRANCH_ADMIN")
            .antMatchers(HttpMethod.PUT, "/api/v1/branch/**").hasAnyRole("ADMIN", "CLAN_LEADER", "BRANCH_ADMIN")
            .antMatchers(HttpMethod.DELETE, "/api/v1/branch/**").hasAnyRole("ADMIN", "CLAN_LEADER", "BRANCH_ADMIN")
            
            /**
             * 5. 成员管理接口 - 分支管理员及以上
             */
            // 成员信息管理
            .antMatchers(HttpMethod.POST, "/api/v1/members/**").hasAnyRole("ADMIN", "CLAN_LEADER", "BRANCH_ADMIN")
            .antMatchers(HttpMethod.PUT, "/api/v1/members/**").hasAnyRole("ADMIN", "CLAN_LEADER", "BRANCH_ADMIN")
            .antMatchers(HttpMethod.DELETE, "/api/v1/members/**").hasAnyRole("ADMIN", "CLAN_LEADER", "BRANCH_ADMIN")
            // 成员导入
            .antMatchers("/api/v1/members/import").hasRole("ADMIN")
            
            /**
             * 6. 小程序用户接口 - 登录用户
             */
            // 家族信息查看
            .antMatchers(HttpMethod.GET, "/api/v1/clan/**").hasAnyRole("MINIAPP", "USER", "BRANCH_ADMIN", "CLAN_LEADER", "ADMIN")
            // 分支信息查看
            .antMatchers(HttpMethod.GET, "/api/v1/branch/**").hasAnyRole("MINIAPP", "USER", "BRANCH_ADMIN", "CLAN_LEADER", "ADMIN")
            // 成员信息查看
            .antMatchers(HttpMethod.GET, "/api/v1/members/**").hasAnyRole("MINIAPP", "USER", "BRANCH_ADMIN", "CLAN_LEADER", "ADMIN")
            // 家族动态
            .antMatchers("/api/v1/familynews/**").hasAnyRole("MINIAPP", "USER", "BRANCH_ADMIN", "CLAN_LEADER", "ADMIN")
            // 成员审核
            .antMatchers("/api/v1/audit/**").hasAnyRole("MINIAPP", "BRANCH_ADMIN", "CLAN_LEADER", "ADMIN")
            
            /**
             * 7. 其他接口 - 需要认证
             */
            .anyRequest().authenticated()
            .and()
            .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
    }

    /**
     * 密码加密器配置
     * 
     * 使用BCrypt算法进行密码加密。
     * BCrypt是一种安全的哈希算法，适合密码存储。
     * 
     * @return BCrypt密码加密器
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    /**
     * CORS跨域配置
     * 
     * 配置跨域资源共享策略，允许前端应用访问API。
     * 支持所有来源、常用HTTP方法和请求头。
     * 
     * @return CORS配置源
     */
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Collections.singletonList("*"));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        configuration.setAllowedHeaders(Collections.singletonList("*"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
} 